package com.ruoyi.generator.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.ImageUtils;
import com.ruoyi.generator.domain.GenTable;
import com.ruoyi.generator.util.DBUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.generator.mapper.WBackupRecordMapper;
import com.ruoyi.generator.domain.WBackupRecord;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 数据备份记录Service业务层处理
 * 
 * @author lynn
 * @date 2023-08-01
 */
@Service
public class WBackupRecordServiceImpl extends ServiceImpl<WBackupRecordMapper, WBackupRecord> implements IWBackupRecordService
{
    @Autowired
    private WBackupRecordMapper wBackupRecordMapper;

    @Autowired
    private IGenTableService genTableService;


    @Transactional
    @Override
    public boolean saveBackupRecord(WBackupRecord wBackupRecord) {
        String tables = wBackupRecord.getTables();
        if(StringUtils.isBlank(tables)){
            throw new ServiceException("请选择需要备份的表！");
        }
        tables = tables.replace(",", " ");
        try {
            String fileUrl = DBUtils.exportDatabaseTool(tables);
            wBackupRecord.setFilePath(fileUrl);
        }catch (Exception e){
            return false;
        }
        return this.save(wBackupRecord);
    }

    @Transactional
    @Override
    public synchronized boolean uploadFileRecover(MultipartFile file) throws IOException {
        // 上传文件路径
        String filePath = RuoYiConfig.getTempFilePath();
        // 上传并返回新文件名称
        String fileName = FileUploadUtils.upload(filePath, file);
        filePath += fileName;
        filePath = filePath.replaceAll(Constants.RESOURCE_PREFIX + "/temp", "");
        // 清空表
        clearTable(filePath);
        DBUtils.recover(filePath);

        // 删除临时文件
        FileUploadUtils.remove(filePath);
        return true;
    }

    @Transactional
    @Override
    public synchronized boolean localFileRecover(WBackupRecord wBackupRecord) throws IOException {
        WBackupRecord backupRecord = this.getById(wBackupRecord.getId());
        // 清空表
        clearTable(backupRecord.getFilePath());
        return DBUtils.recover(backupRecord.getFilePath());
    }

    @Override
    public void systemBackupTask() {
        GenTable genTable = new GenTable();
        List<GenTable> genTables = genTableService.selectDbTableList(genTable);

        List<String> tableNames = genTables.stream().map(GenTable::getTableName).collect(Collectors.toList());

        List<String> excludeTableNames = new ArrayList<>();
        excludeTableNames.add("sys_job_log");
        excludeTableNames.add("sys_oper_log");
        excludeTableNames.add("sys_logininfor");
        tableNames.removeAll(excludeTableNames);

        WBackupRecord wBackupRecord = new WBackupRecord();
        wBackupRecord.setRemark(DateUtils.getDate() + "系统备份");
        wBackupRecord.setBackupType(3);
        wBackupRecord.setTables(tableNames.stream().collect(Collectors.joining(",")));
        this.saveBackupRecord(wBackupRecord);
    }

    private void clearTable(String fileUrl) throws IOException {
        InputStream is = ImageUtils.getFile(fileUrl);
//        InputStream is = ImageUtils.getFile("D:/test/test3.sql");

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        List<String> readlist = new ArrayList<String>();
        String line = null;
        while ((line = br.readLine()) != null) {
            if(line.contains("-- Dumping data for table `")){
                line = line.substring(27, line.length() - 1);
                readlist.add(line);
                wBackupRecordMapper.clearTable(line);
            }

        }

        br.close();
        is.close();
    }
}
